from django.shortcuts import render
from django.views import View
from django.http import JsonResponse
from django_redis import get_redis_connection
from meiduo_mall.utils.cookiesecret import CookieSecret
from goods.models import SKU

import json
# Create your views here.

"""
存储数据：　用户id(user_id)　商品ｉｄ(sku_id) 数量(count) 勾选状态(selected)
１．用户已登陆：(存储在Redis)
    存储数据格式,分开存储：
        １．商品信息(使用hash存储对象)：　carts_user_id: {sku_id1: count, sku_id2: count}  # carts_15: {1: 2, 2:2}
                    redis操作命令：　hset() hdel() hgetall()
        2.勾选状态的商品(set:自动去重)：　selected_user_id: {sku_id1, sku_id2, sku_id3}
                    redis操作命令：　sadd(增) srem(删) smembers(返回所有元素)
２．用户未登陆:(存储在Cookie)
    存储数据格式:　{"sku_id1": {"count":5, "selected":}}
        处理编码解码（pickel,base64）　dumps,loads,

    添加购物车步骤：
        1.提取参数
        2.校验参数
        3.业务处理－－添加购物车
         3.1 判断用户是否登陆: is_autheticate
            3.1.1 用户已登陆
                1.获取redis中数据：　get_redis_connect
                2.构建新数据：
                    判断商品是否存在，存在则累加 count
                    不存在新增: hset()


"""

class CartsView(View):

    # 添加购物车
    def post(self, request):

        # 1.提取参数
        user = request.user
        data = json.loads(request.body.decode())
        sku_id = data.get("sku_id")
        count = data.get("count")
        selected = data.get("selected", True)

        # 2.校验参数
        if not all([sku_id, count]):
            return JsonResponse({"code": 400, "errmsg": "缺少参数"})

        # 3.业务处理－－添加购物车
        #  3.1 判断用户是否登陆: is_authenticate
        if user.is_authenticated:
        # 3.1.1 用户已登陆
            # 1.获取redis中数据：
            conn = get_redis_connection("carts")
            redis_carts = conn.hgetall("carts_%s"%user.id)
            redis_selected = conn.smembers("selected_%s"%user.id)
            #2.构建新数据：
            # 判断商品是否存在，存在则累加 count ,不存在新增: hset()
            if str(sku_id).encode() in redis_carts:
                count = count + int(redis_carts[str(sku_id).encode()])
                conn.hset("carts_%s"%user.id, sku_id, count)
            else:
                conn.hset("carts_%s"%user.id, sku_id, count)

            if selected:
                conn.sadd("selected_%s"%user.id, sku_id)
            else:
                conn.srem("selected_%s"%user.id, sku_id)

            return JsonResponse({"code": 400, "errmsg": "ok"})

        else:
            # 用户未登陆
            # 获取Cookie中数据
            cart_str = request.COOKIES.get("carts")

            if cart_str:
                cart_dict = CookieSecret.loads(cart_str)  # 解码
            else:
                cart_dict = {}

            # 存储数据格式:　{"sku_id1": {"count": 5, "selected":}}
            if sku_id in cart_dict:
                cart_dict[sku_id]["count"] += count
                cart_dict[sku_id]["selected"] = selected
            else:
                cart_dict[sku_id] = {
                    "count": count,
                    "selected": selected
                }

            response = JsonResponse({"code": 0, "errmsg": "ok"})
            # 编码
            cart_str = CookieSecret.dumps(cart_dict)
            response.set_cookie("carts", cart_str)
            return response

    # 展示购物车
    def get(self, request):
        #
        user = request.user
        # cart_dict = {1: {"count": 5, "selected": True}}
        cart_dict = {} # 准备一个空字典来保存购物车数据  ×××构建一个已登陆和未登陆共有的结构，构建响应共用同一结构，精简代码

        if user.is_authenticated:
            # redis 登陆
            conn = get_redis_connection("carts")
            # redis_carts = {b'1': b'5', b"4": b'1'}  {sku_id1: count, sku_id2: count}
            redis_carts = conn.hgetall("carts_%s"%user.id)
            redis_selected = conn.smembers("selected_%s"%user.id)

            for k,v in redis_carts.items():
                sku_id = int(k)
                count = int(v)
                cart_dict[sku_id] = {
                    "count": count,
                    "selected": k in redis_selected
                }

        else:
            # 未登陆
            cart_str = request.COOKIES.get("carts")
            if cart_str:
                cart_dict = CookieSecret.loads(cart_str)

        cart_skus = []
        sku_ids = cart_dict.keys()
        for sku_id in sku_ids:
            sku = SKU.objects.get(pk=sku_id)
            cart_skus.append({
                "id": sku.id,
                "name": sku.name,
                "default_image_url": sku.default_image.url,
                "price": sku.price,
                "count": cart_dict[sku_id]["count"],
                "selected": cart_dict[sku_id]["selected"]
            })

        return JsonResponse({
            "code": 0,
            "errmsg": "ok",
            "cart_skus": cart_skus
        })

    # 修改购物车
    def put(self, request):
        #
        user = request.user
        data = json.loads(request.body.decode())
        sku_id = data.get("sku_id")
        count = data.get("count")
        selected = data.get("selected", True)

        if not all([sku_id, count]):
            return JsonResponse({"code": 400, "errmsg": "缺少参数"})

        if user.is_authenticated:
            # carts_user_id: {sku_id1: count, sku_id2: count}
            conn = get_redis_connection("carts")
            # (1)、更新redis购物车的商品数量
            conn.hset("carts_%s"%user.id, sku_id, count)
            # (2)、更新redis购物车的选中状态
            if selected:
                conn.sadd("selected_%s"%user.id, sku_id)
            else:
                conn.srem("selected_%s"%user.id, sku_id)

            sku = SKU.objects.get(pk=sku_id)
            response = JsonResponse({
                "code": 0,
                "errmsg": "ok",
                "cart_sku": {
                    "id": sku.id,
                    "count": count,
                    "selected": selected,
                    "name": sku.name,
                    "default_image_url": sku.default_image.url,
                    "price": sku.price,
                    "amount": sku.price * count
                }
            })
            return response

        else:
            carts_str = request.COOKIES.get("carts")
            if carts_str:
                carts_dict = CookieSecret.loads(carts_str)
            else:
                carts_dict = {}

            if sku_id in carts_dict.keys():
                carts_dict[sku_id]["count"] = count
                carts_dict[sku_id]["selected"] = selected

            carts_str = CookieSecret.dumps(carts_dict)

            sku = SKU.objects.get(pk=sku_id)
            response = JsonResponse({
                "code": 0,
                "errmsg": "ok",
                "cart_sku": {
                    "id": sku.id,
                    "count": count,
                    "selected": selected,
                    "name": sku.name,
                    "default_image_url": sku.default_image.url,
                    "price": sku.price,
                    "amount": sku.price * count
                }
            })
            response.set_cookie("carts", carts_str, max_age=24 * 3600 * 14)
            return response

    # 删除购物车
    def delete(self, request):
        #
        user = request.user
        data = json.loads(request.body.decode())
        sku_id = data.get("sku_id")

        if user.is_authenticated:
            conn = get_redis_connection("carts")
            # redis_carts = {b'1': b'5', b"4": b'1'}  {sku_id1: count, sku_id2: count}
            conn.hdel("carts_%s"%user.id, sku_id)
            conn.srem("selected_%s"%user.id, sku_id)

            return JsonResponse({"code": 0, "errmsg": "ok"})
        else:
            # 未登陆，删除cookie购物车商品 —— 删除购物车中的某一个商品
            cart_str = request.COOKIES.get("carts")
            # {"sku_id": {"count": 1, "selected": True},}
            if cart_str:
                cart_dict = CookieSecret.loads(cart_str)
            else:
                cart_dict = {}

            # (2)、删除购物车字典中的sku_id
            if sku_id in cart_dict:
                cart_dict.pop(sku_id)

            cart_str = CookieSecret.dumps(cart_dict)
            response = JsonResponse({"code": 0, "errmsg": "ok"})
            response.set_cookie("carts", cart_str, max_age=24 * 3600 * 14)
            return response


# 全选购物车
class CartsSelectAllView(View):

    def put(self, request):

        user = request.user
        data = json.loads(request.body.decode())
        selected = data.get("selected")

        if not isinstance(selected, bool):
            return JsonResponse({"code": 400, "errmsg": "参数错误"})

        # 3、业务数据处理 —— 登陆，把redis购物车设置全选或取消；未登陆把Cookie购物车设置全选或取消；
        if user.is_authenticated:
            # (1)、获取redis购物车商品数据
            conn = get_redis_connection("carts")
            redis_carts = conn.hgetall("carts_%s"%user.id)
            # redis_selected = conn.smembers("selected_%s"%user.id)
            sku_id = redis_carts.keys()
            # (2)、把全部sku_id加入集合或从集合中去除
            if selected:
                conn.sadd("selected_%s"%user.id, *sku_id) # *sku_id 函数调用时拆包 sadd('selected_%s'%user.id, b'1', b'2')
            else:
                conn.srem("selected_%s"%user.id, *sku_id)

            return JsonResponse({"code": 0, "errmsg": "ok"})

        else:
            # cookie
            cart_str = request.COOKIES.get("carts")
            if cart_str: # 必须判断，若cart_str为None,CookieSecret.loads方法会报错,不能为空
                cart_dict = CookieSecret.loads(cart_str)
            else:
                cart_dict = {}

            for sku_id,v in cart_dict.items():
                print(sku_id)
                cart_dict[sku_id]["selected"] = selected

            cart_str = CookieSecret.dumps(cart_dict)
            response = JsonResponse({"code": 0, "errmsg": "ok"})
            response.set_cookie("carts", cart_str, max_age=24 * 3600 * 14)
            return response


# 展示商品页面简单购物车
class CartsSimpleView(View):

    def get(self, request):
        #
        user = request.user
        cart_dict = {}  # 先定义一个共用结构{１: {"count": 2, "selected": True}, 2: {"count": 5, "selected": False}}

        if user.is_authenticated:
            # redis
            conn = get_redis_connection("carts")
            redis_cart = conn.hgetall("carts_%s"%user.id)
            redis_selected = conn.smembers("selected_%s"%user.id)

            for sku_id in redis_selected:
                cart_dict[int(sku_id)] = {
                    "count": int(redis_cart[sku_id]),
                    "selected": True
                }

        else:
            cart_str = request.COOKIES.get("carts")
            if cart_str:
                cart_dict_cookie = CookieSecret.loads(cart_str)
            else:
                cart_dict_cookie = {}

            for sku_id,cart_sku in cart_dict_cookie.items():
                if cart_sku["selected"]:
                    cart_dict[sku_id] = {
                        "count": cart_sku["count"],
                        "selected": True
                    }

        # 根据cart_dict，去读取mysql商品详细信息，构建响应
        cart_skus = []
        for sku_id in cart_dict.keys():
            sku = SKU.objects.get(pk=int(sku_id))
            cart_skus.append({
                "id": sku.id,
                "name": sku.name,
                "count": cart_dict[sku_id]["count"],
                "default_image_url": sku.default_image.url
            })

        return JsonResponse({
            "code": 0,
            "errmsg": "ok",
            "cart_skus": cart_skus
        })
















